				Introduction

S-Lang (pronounced ``sssslang'') is a simple stack based language
interpreter which may be easily embedded into another application making it
extensible.

Although the language is stack based, it has many features found in higher
level languages.  This includes both global variables and local variables,
branching, looping constructs, as well as functions.  In many ways it
resembles postscript which is also stack based.

The syntax of the language is quite simple.  To keep the parsing stage
simple and fast, Reverse Polish Notation (RPN) is used throughout.

It is perhaps easiest to explain the syntax of the language by analogy with
other popular languages.  I will choose C because C has influenced the look
of S-Lang.

------------------------------------------------------------
C-Like language            |     S-Lang        
------------------------------------------------------------
Global_Variable_List	   |     [global variables]
			   |
function(parameter_list)   |	 (
{			   |        [parameter list]
  local_variable_list	   |        [local variables]
			   |
  statement1		   |        statement1
     .			   |            .
     .			   |            .
  statementn		   |        statementn
}			   |      ) function
                           |                            
------------------------------------------------------------
Here is an actual example.  This example computes the sum of the first n
integers and returns it.

int compute_sum(int n)            |     ( [n] =n
{ 				  |    
   int sum, i;			  |       [sum i] 
   				  |    
   sum = 0;			  |       0 =sum
   for (i = 1; i <= n; i = i + 1) |       1 n 1 
     {				  |         {  =i
        sum = sum + i;		  |            i sum + =sum
     }				  |         } for
     				  |    
   return (sum);		  |       sum
}				  |     ) compute_sum


The similarities of the program should be obvious.  Experienced Slang
programmers would never write this program as I have done above.  I have
chosen to write it this way for pedagogical purposes.  A much better way
would be to do:

			( [n sum] =n 0 =sum
			  1 n 1 { sum + =sum } for
			  sum
			) compute_sum

The important thing to realize is that all variables must be declared before
they can be used.  This is done by enclosing them in brackets.  Also note
that [n sum] is equivalent to [n] [sum].  

Variables declared within a function are considered local variables and hide
the definition of global variables of the same name.

In C, one would call the function compute_sum with parameter 100 and assign
it to a variable y as:

			    y = compute_sum(100);
  
In should be apparant that to perform this same task in S-Lang, one writes:

			     100 compute_sum =y
			     
Please note that there can be no space between the equals sign `=' and the
variable upon which it performs the assignment.


			    Arithmetic operators.

The arithmetic operators `+', `-', `*', `/' operate on integers. They are
defined:

	       x y +	-->	 x + y
	       x y -	-->	 x - y
	       x y *	-->	 x * y
	       x y /	-->	 x / y

These operators remove the top two values from the stack and put the result
of the operation on the stack.

			     Binary Operations.

The binary Boolean operators act on two integers and return an integer.  An
integer is considered TRUE if it is non-zero otherwise it is FALSE.  These
operators are

	       x y ==  	  ;; TRUE if x equals y
	       x y !=	  ;; TRUE if x is not equal to y
	       x y >	  ;; TRUE if x is greater than y 
	       x y >=	  ;; TRUE if x is greater than or equal to y 
	       x y <	  ;; TRUE if x is less than y 
	       x y <=	  ;; TRUE if x is less than or equal to y 
	       x y or	  ;; TRUE if either x or y are TRUE
	       x y and	  ;; TRUE if both x and y are TRUE

Here the operator ``pops'' the two variable off the stack and replaces it by
the value of the result, TRUE or FALSE (non-zero or zero).  

In addition to the above LOGICAL operators, S-Lang also incorporates
operators which act on the bits themselves.  These are: 

               x y &      ;; bitwise and
               x y |      ;; bitwise or
               x y xor    ;; bitwise exclusive or


			       Unary operators
			       
The UNARY operators operate only on one integer.  They are: 

	x not   ;; if x is non zero return zero else return non zero
	x chs   ;; change the  sign of x
	x ~     ;; bitwise not
	
	
			       Stack Operators

The use of local variables greatly simplifies the task of maintaining the
stack stack.  Nevertheless, S-Lang is a stack based language and there are
times when they are useful.

	       pop  	  ;; removes the top object fro the stack
	       dup  	  ;; duplicates the top object on the stack

These operators work on all data types--- they are not limited to integers.

			       Block Operators

A Block is a sequence of valid executable S-Lang code.  As such, a block may
contain other blocks.  However, a block cannot include function
declarations; function declarations must take place at top level.  

The statements that comprise a block must be enclosed in curly brackets
`{}'.  Blocks are used for looping and branching.  Hence, block operators
are `while',  `for',  `if', etc.... 

   n {block} if			;; executes block if n is TRUE
   n {block} !if		;; executes block if n is FALSE
   n {block1} {block2} else	;; block1 if n is TRUE else block2
   n {bock} loop		;; executes block n times if n is positive
	 
The other block operations are more complex and require explanation.  Starting
with the simplest...

 {cond}{block} while	;; repeatedly executes block while cond is true.

 first last step	;; pops top three values from the stack as step, last
   {block} for 		;; and first, in that order.  If first is less than or
   			;; equal to last, it pushes first onto the stack and
			;; executes the block.  It then increments first by 
			;; step and repeats the process.

 {block1} ... {blockn}  ;; The orelse operator operates on a series of 1 or
   orelse		;; more blocks.  It executes the first block then tests
   			;; the top of the stack.  If it is FALSE, it executes
			;; the second block.  It continues to do so until one
       			;; of the blocks returns TRUE.  It is important to note
			;; that it does not pop the top element from the stack
			;; to perfor the test.  The stack gets propagated 
			;; through the blocks so that one block can use the 
			;; results of the previous one.
			
 {block1} ... {blockn}  ;; The andelse is just like the orelse except that it
  andelse 		;; continues to execute the blocks until one returns
  			;; FALSE.

 x {block1}		;; Switch statement.  Here blocks are ``tested'' for 
      .			;; a match against object x.  If a block ``matches''
      .			;; it is executed.  A typical block must conatin the
   {blockn}		;; colon operator `:' which in somes sense serves as
 switch			;; a label.  When execution reaches this operator, an
 			;; integer is poped off the stack.  If TRUE, a match 
			;; exists and the rest of the block is executed.  
			;; Otherwise, control is passed to the next block.
			
Since the switch structure is complicated, consider the following example: 

( [ch] =ch  ;; function is passed an integer

   ch { 32  == : page_down }   ;; ascii space character
      { 127 == : page_up }     ;; delete char is page_up
      { "q" int == :  quit }  ;; quit!
      { pop "Unknown command"  error } ;; default
      switch
) cmd_dispatch

Here, an integer is passed to the function cmd_dispatch.  The switch
statement pops the first element from the stack and pushes it back before
control is passed to a block.  For example, suppose the function is called
as in:  

			      127 cmd_dispatch
			      
Then 127 is pushed onto the stack and the block { 32 == : page_down } is 
executed.  127 32 == leaves 0 on the stack.  When the colon operator  is
encountered,  the integer is poped from the stack and if TRUE, the rest of
the block is executed.  In this case, a 0 is returned so the block is
aborted and control returns to the second block.  In this case, 127 127 ==
returns 1 and a match is said to be made.  Then page_up is called and
control passes to the statements following the switch keyword.  C
programmers would write the above example as: 

void cmd_dispatch(char ch)
{
   switch(ch)
   {
      case 32: page_down;  break;
      case 127: page_up; break;
      case 'q': quit; break;
      default: error("Unknown Command");
   }
}


  
   

			      String Operators
			      
The previous operators act upon integers and blocks.  The operators in this
section act on character strings.  

      s strlen		;; pops string and returns its length
      s1 s2 strcat	;; concatenates strings to s1s2 popping s1 and s2
      s1 s2 strcmp	;; returns 0 if s1 and s2 are the same, a negative 
      			;; number if s1 is lexically greater, otherwise it
			;; returns a positive non-zero integer (s1 ``>''s2)
			
			      Array Operations
			      
s n1 n2 .. nd d create_array
                        ;; creates d dimensional array[n1, n2, ... nd] of 
			;; type s.  Here s (string) is one of 
			;;   "i" integer
			;;   "s" string
			;;   "f" float
			;; It returns pointer to array on stack.
			
a free_array            ;; frees previously created array pointed to by a

n1 n2 ... nd a aget     ;; returns array element a[n1, n2,...nd] to stack
x n1 n2 ... nd a aput   ;; assigns x to array element a[n1, n2,...nd]

Since the array may be hard to understand, here is an example routine 
to compute trace of an nxn matrix of integers

( [n a] =a  ;; assumes array a on stack as well as size

  [sum i] 0 =sum
  
  1 n 1                 ;; array elements always start at 1
    {
      =i
      i a aget sum +
    } for
  sum
) trace

;;; this routine creates a 10x10 array and sets it diagonal elements to 5

[a]  "i" 10 10 2 create_array =a
     1 10 1 { =i
              5 i i a aput
	    }
	  for



      
			      Transfer Functions
			      
These operators convert data from one type to another.

      n string		;; converts integer n to its string equivalent.
      
      n char		;; converts integer to a string of length 1 whose first
			;; character has ascii value n

      s int		;; returns the ascii value of the first character in
      			;; the string

			   Miscellaneous Functions
			   
      s isdigit		;; returns TRUE if the first character of string s is
      			;; a digit (0-9)
			
      s eval		;; evaluates string s as S-Lang code.
      
      s defined?	;; returns TRUE if string s is the name of a variable
      			;; or function

The operations described above are the only ones intrinsic to the S-Lang
language.  However, S-Lang is meant to be embedded into an application which
would then add new intrinsic operations to the language (e.g., the JED
editor).  It is impossible to say more about these functions without
explicit reference to the application.
